package com.adminserver.util.rsaUtil;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.digest.DigestUtil;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;

@Component
public class RsaUtil {
    /**
     * RSA私钥加密
     *
     * @param str        要加密的数据
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return Base64编码的密文
     */
    public String RsaPriEncrypt(String str, String publicKey, String privateKey) {
        RSA rsa = new RSA(privateKey, publicKey);
        String encryptBase64 = rsa.encryptBase64(str, KeyType.PrivateKey);
        return encryptBase64;
    }

    /**
     * RSA公钥解密
     *
     * @param str        要解密的数据
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return 明文
     */
    public String RsaPubDecrypt(String str, String publicKey, String privateKey) {
        RSA rsa = new RSA(privateKey, publicKey);
        String decryptStr = rsa.decryptStr(str, KeyType.PublicKey, CharsetUtil.CHARSET_UTF_8);
        return decryptStr;
    }

    /**
     * RSA公钥加密
     *
     * @param str        要加密的数据
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return Base64编码的密文
     */
    public String RsaPubEncrypt(String str, String publicKey, String privateKey) {
        RSA rsa = new RSA(privateKey, publicKey);
        String encryptBase64 = rsa.encryptBase64(str, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        return encryptBase64;
    }

    /**
     * RSA私钥解密
     *
     * @param str        要解密的密文
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return 明文
     */
    public String RsaPriDecrypt(String str, String publicKey, String privateKey) {
        try {
            RSA rsa = new RSA(privateKey, publicKey);
            String decryptStr = rsa.decryptStr(str, KeyType.PrivateKey, CharsetUtil.CHARSET_UTF_8);
            return decryptStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 签名
     *
     * @param str        要签名的数据
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return HashMap<String, String>（strAbs，strAbsSign）
     */
    public HashMap<String, String> RsaSign(String str, String publicKey, String privateKey) {
        // 数据摘要
        String strAbs = DigestUtil.md5Hex(str);
        // 公钥签名
        Sign sign = SecureUtil.sign(SignAlgorithm.MD5withRSA, privateKey, publicKey);
        String strAbsSign = Base64.encode(sign.sign(strAbs.getBytes(StandardCharsets.UTF_8)));
        HashMap<String, String> map = new HashMap<>(2);
        map.put("strAbs", strAbs);
        map.put("strAbsSign", strAbsSign);
        return map;
    }

    /**
     * 验签
     *
     * @param str        要验证的数据
     * @param strAbsSign base64编码的签名
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return true/false
     */
    public boolean RsaVerify(String str, String strAbsSign, String publicKey, String privateKey) {
        Sign sign = SecureUtil.sign(SignAlgorithm.MD5withRSA, privateKey, publicKey);
        boolean verify = sign.verify(str.getBytes(StandardCharsets.UTF_8), Base64.decode(strAbsSign));
        return verify;
    }
}
